<template>
	<view style="width: 100%">
		<view class="selectInput" @tap="open">
			<view class="left">
				<text class="placeholder" v-show="!props.modelValue.length">
					{{ props.placeholder }}
				</text>
				<text v-show="props.modelValue.length">
					{{
						props.options
							.filter((item) =>
								props.modelValue.includes(item[props.attrs.value]),
							)
							.map((i) => i[props.attrs.label])
							.join('、')
					}}
				</text>
			</view>
			<view class="right">
				<uni-icons type="down" size="13"></uni-icons>
			</view>
		</view>
		<uni-popup ref="popupRef" :safe-area="false" type="bottom">
			<view class="content">
				<view class="header">
					<div class="title">请选择</div>
					<uni-icons
						class="icon"
						type="closeempty"
						size="16"
						@click="onClose"
					></uni-icons>
				</view>

				<!-- 搜索框 -->
				<view class="search-box" v-if="props.search">
					<input
						class="input"
						type="text"
						placeholder="请选择关键字搜索"
						v-model="queryKeyword"
						@confirm="onQuery"
					/>
					<view class="btn" @click="onQuery">搜索</view>
				</view>
				<view class="main">
					<checkbox-group @change="changeCheck">
						<view
							class="label"
							v-for="item in props.options"
							:key="item[props.attrs.value]"
                            v-show="!search || (search&& (!searchValue || 
                                            props.labelOptions.length > 0 ? 
                                            (props.labelOptions.map((labelOption) => item[labelOption])
                                            .filter((val) => !!val)
                                            .join('-')).includes(searchValue)
                                        : item[props.attrs.label].includes(searchValue)))"
						>
							<checkbox
								:class="{checked: selectData.includes(item[props.attrs.value])}"
								:value="item[props.attrs.value]"
								:checked="selectData.includes(item[props.attrs.value])"
								@click="handleItemClick(item)"
							/>
							<template v-if="props.labelOptions.length > 0">
								{{
									props.labelOptions
										.map((labelOption) => item[labelOption])
										.filter((val) => !!val)
										.join('-')
								}}
							</template>
							<template v-else>
								{{ item[props.attrs.label] }}
							</template>
						</view>
					</checkbox-group>
				</view>
				<view class="footer mb-24rpx">
					<view
						class="width-100 height-80rpx bg-primary-color font-color-white border-radius-72rpx flex justify-center align-center"
						@click="onConfirm"
					>
						确认
					</view>
				</view>
			</view>
		</uni-popup>
	</view>
</template>

<script setup lang="ts">
	import {PropType, ref} from 'vue';
	import _ from 'lodash';

	const props = defineProps({
		modelValue: {
			type: Array,
			default: () => [],
		},
		options: {
			type: Array,
			default: () => [],
		},
		attrs: {
			type: Object,
			default: () => ({label: 'text', value: 'value'}),
		},
		placeholder: {
			type: String,
			default: () => '请选择内容',
		},
		labelOptions: {
			type: Array as PropType<Array<string>>,
			default: () => [],
		},
		labelSplit: {
			type: String,
			default: () => '',
		},

		// 是否开启搜索功能
		search: {
			type: Boolean,
			default: false,
		},
	});

	// 搜索关键字
	const queryKeyword = ref('');

	const popupRef = ref(null);
	const selectData = ref([]);
	const emit = defineEmits(['change', 'update:modelValue', 'remove', 'search']);

	const removedList = ref([]);

	/**
	 * 编辑之前选中的值
	 * 在搜索后将编辑之前选中的值给赋到selectData里
	 */
	const selectedBeforeEdit = ref([]);

	/**
	 * 搜索事件
	 */
    const searchValue = ref('')
	const onQuery = () => {
        searchValue.value = queryKeyword.value
		emit('search', queryKeyword.value);
	};

	const open = () => {
		removedList.value.length = 0;
		selectData.value = props.modelValue;
		selectedBeforeEdit.value = _.cloneDeep(props.modelValue);
		if (popupRef.value) {
			popupRef.value.open();
		}
	};

	const onConfirm = () => {
		queryKeyword.value = '';
		if (
			selectedBeforeEdit.value &&
			Object.prototype.toString.call(selectedBeforeEdit.value).includes('Array')
		) {
			selectedBeforeEdit.value.forEach((item) => {
				if (
					!selectData.value.includes(item) &&
					!removedList.value
						.map((removedItem) => removedItem[props.attrs.value])
						.includes(item)
				) {
					selectData.value.push(item);
				}
			});
		}

		emit('update:modelValue', selectData.value);
		emit('change', selectData.value);
		emit('remove', removedList.value);
		onQuery();
		onClose();
	};
	const changeCheck = (e) => {
		selectData.value = e.detail.value;
	};
	const onClose = () => {
		if (popupRef.value) {
			popupRef.value.close();
		}
	};

	/**
	 * 选项点击事件
	 * 主要用于取消选中后返回反选的值供给父组件使用
	 * @param {object} e - 选项对象
	 */
	const handleItemClick = (e) => {
		if (!selectData.value.includes(e[props.attrs.value])) {
			removedList.value.push(e);
		}
	};
</script>

<style lang="scss" scoped>
	.content {
		padding: 20rpx;
		background-color: #fff;
		border-top-left-radius: 16rpx;
		border-top-right-radius: 16rpx;

		.header {
			position: relative;
			text-align: center;
			padding: 20rpx;
			.icon {
				position: absolute;
				right: 20rpx;
				top: 20rpx;
			}
		}

		.search-box {
			display: flex;
			column-gap: 24rpx;
			align-items: center;
			font-size: 24rpx;

			.input {
				flex: 1;
				width: 0;
				height: 64rpx;
				border-radius: 64rpx;
				background-color: rgba(242, 243, 245, 1);
				padding: 0 24rpx;
			}

			.btn {
				color: #007cff;
			}
		}

		.main {
			height: 500rpx;
			overflow: auto;
			padding: 20rpx;
			margin-top: 40rpx;
			.label {
				margin-bottom: 20rpx;
			}
		}
		.footer {
			.btn {
				border-radius: 200rpx;
			}
		}
	}
	.selectInput {
		font-size: 0.875rem;
		border: 1px solid #e5e5e5;
		box-sizing: border-box;
		border-radius: 0.25rem;
		padding: 0 0.3125rem;
		padding-left: 0.625rem;
		position: relative;
		display: flex;
		-webkit-user-select: none;
		user-select: none;
		flex-direction: row;
		align-items: center;
		border-bottom: solid 1px #e5e5e5;
		width: 100%;
		flex: 1;
		// height: 2.1875rem;
		min-height: 2.1875rem;
		display: flex;
		justify-content: space-between;
		.left {
			flex: 1;
		}
		.placeholder {
			color: #6a6a6a;
		}
	}
	::v-deep.uni-checkbox-input {
		border-radius: 100%;
		background-color: #fff;
		svg {
			color: #fff;
			path {
				fill: #fff;
			}
		}
	}
	.checked {
		::v-deep.uni-checkbox-input {
			background-color: #007aff;
		}
	}
</style>
